﻿using Microsoft.Extensions.Logging;
using System.Text.RegularExpressions;
using XCode;
using Zdap.Common;
using Zdap.Common.AutoMapper;
using Zdap.Common.Enums;
using Zdap.Common.Extensions;
using Zdap.Common.IdGenerate;
using Zdap.XCode.Service;

namespace Datav.Design.Service
{
    internal sealed class StudentSubmitAnswerService
    {
        private IServiceFactory _serviceFactory;
        private readonly ILogger<StudentSubmitAnswerService> _logger;

        private StudentGradeDetail grade;

        private QuestionsAnswerModel questionAnswer;//题目的答案信息
        private int errorShowType = 0;//是否标红  0隐藏1显示
        private int scoreShowType = 0;//是否显示得分 0隐藏1显示

        /// <summary>
        ///
        /// </summary>
        /// <param name="serviceFactory"></param>
        public StudentSubmitAnswerService(IServiceFactory serviceFactory)
        {
            _serviceFactory = serviceFactory;
            _logger = _serviceFactory.Resolve<ILogger<StudentSubmitAnswerService>>();
        }

        /// <summary>
        /// 学生提交作答
        /// 驳回需求：例：物料申请单，后台设置了驳回时，考生A答题错误，点提交，则此时弹窗驳回提示。放弃，则本题计为0分，
        /// 即侧边栏，绑定知识点、选择公章以及节点内的数据均不得分
        /// 驳回题 作答放弃时实现逻辑：
        /// 1.学生点击放弃按钮调用 SubmitAnswer 接口，IsGiveUp=true ,发送消息
        /// 2.消费服务消费该条消息，单独处理 放弃 的逻辑，把改题目所有的作答记录详情（包括：表单题、依据、盖章、知识题、调度引用）设置为已放弃
        /// </summary>
        /// <param name="model"></param>
        /// <param name="currentUser"></param>
        /// <returns></returns>
        public async Task<ResponseContext<AnswerCompareResultModel>> SubmitAnswer(SubmitAnswerModel model, UserTicket currentUser)
        {
            var result = new ResponseContext<AnswerCompareResultModel>();
            try
            {
                model.UserId = currentUser.Id;
                var isCan = await CheckCanSubmitAnswer(model);

                if (!isCan.IsSuccess)
                    return result.SetError(isCan);

                //model.TaskId = grade.TaskId;//保存任务id到提交参数中
                //model.ProjectId = grade.ProjectId;

                if (grade != null)
                {
                    model.GradeId = grade.Id;
                    model.Id = grade.Id;
                }

                CheckGradeDetail(model);//检查用户是否已经作答，并做相应处理

                AnswerCompareResultModel answerCompareResult = null;
                if (model.IsReadonly || model.NoAutoScore)//只看的题目、非自动判分题。0是自动判分1是非自动判分，不对比答案直接提交
                {
                    answerCompareResult = new()
                    {
                        AnswerResult = AnswerResultStatus.Right,
                        QuestionsId = model.QuestionsId
                    };
                }
                else//必须填写答案自动评分的题目
                {
                    //对比答案
                    var compareRltResp = await CompareAnswer(model);

                    if (!compareRltResp.IsSuccess)
                    {
                        if (compareRltResp.Code == WdCommonConstants.StudentAnswerField)//如果学生提交的答案缺少字段，直接保存答案
                        {
                            // 发送消息
                            //await PublishGradeDetailMessage(model, new AnswerCompareResultModel { Score = 0, AnswerResult = AnswerResultStatus.Error });
                        }
                        return result.SetError(compareRltResp);
                    }
                    answerCompareResult = compareRltResp.Data;
                }

                answerCompareResult.Id = model.Id; //设置返回的作答详情Id

                // 发送消息
                await PublishGradeDetailMessage(model, answerCompareResult);

                //await UpdateQuestionAccuracy(model, answerCompareResult.AnswerResult);

                if (errorShowType == 0)//不标红,不显示得分
                {
                    answerCompareResult.AnswerCompareInfo = null;
                }
                if (scoreShowType == 0)//不显示作答得分
                {
                    answerCompareResult.SumScore = answerCompareResult.Score = 0;
                }
                else
                {
                    answerCompareResult.SumScore = answerCompareResult.Score;
                }

                return result.SetSuccess(answerCompareResult);
            }
            catch (Exception ex)
            {
                _logger.LogError($"提交作答异常，异常信息：{ex},提交的答案：{model.ToJson()}");
                return result.SetError($"提交作答异常,题目:{model.QuestionsId}，异常信息：{ex}");
            }
        }
        private static async void CheckGradeDetail(SubmitAnswerModel model)
        {
            if (model.Id > 0)//id 已存在，直接跳过
                return;

            //检查学生是否已经作答
            var (isExists, gradeDetailId, _) = await StudentGradeDetail.CheckStudentSubmitAnswer(model.GradeId, model.QuestionsId);

            if (!isExists)//学生为作答过
            {
                model.Id = IdWorker.NextId();
                model.IsAdd = true;
            }
            else
            {
                model.Id = gradeDetailId;
            }
        }
        ///// <summary>
        ///// 获取题目得分的总分
        ///// 作答计分:  当提交时，总分为整个题目的分值，包括公章、引用依据、引用知识点、引用、场景调度
        ///// </summary>
        ///// <param name="model"></param>
        ///// <returns></returns>
        //private async Task<decimal> GetQuestionsSumScore(SubmitAnswerModel model)
        //{
        //    var score = 0M;
        //    var where = StudentGradeDetail._.AnswerGroupId == model.AnswerGroupId & StudentGradeDetail._.QuestionsId == model.QuestionsId;
        //    if (model.QuestionsSubId > 0) where &= StudentGradeDetail._.QuestionsSubId != model.QuestionsSubId;//单元格引用(场景数据调度)题 的 QuestionId
        //    else where &= StudentGradeDetail._.QuestionDataType != model.QuestionDataType;//排除当前题目的 题目数据类型
        //    var gradeDetails = await StudentGradeDetail.FindAllAsync(where, null, $"{StudentGradeDetail.__.Score}", 0, 0);
        //    if (gradeDetails.Count > 0)
        //    {
        //        score = gradeDetails.Sum(x => x.Score);
        //    }
        //    return score;
        //}

        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private async Task<ResponseContext<AnswerCompareResultModel>> CompareAnswer(SubmitAnswerModel model)
        {
            var result = new ResponseContext<AnswerCompareResultModel>();
            AnswerCompareResultModel answerCompareResult;
            var questionAnswerRepository = _serviceFactory.Resolve<IQuestionAnswerRepository>(model.QuestionType.ToString());
            //var questionAnswerRepository = _serviceFactory.Resolve<IQuestionAnswerRepository>();
            //获取题目信息
            questionAnswer = questionAnswerRepository.GetQuestionInfo(new QuestionInfoRequest { Id = model.QuestionsId });
            if (questionAnswer == null) return result.SetError("题目信息不存在。");
            if (questionAnswer.Answer.IsNullOrEmpty()) return result.SetError("题目的答案为空。");

            //学生放弃的题目和仅查看题目 提交的答案可以为空
            if (!questionAnswer.IsReadonly && model.Answer.IsNullOrWhiteSpace())
                return result.SetError("答案为空，请填写答案后再提交。");

            var answerCompareService = _serviceFactory.Resolve<IAnswerCompareService>();

            var compareResult = answerCompareService.CompareAnswer(model, questionAnswer); //对比答案

            if (!compareResult.IsSuccess)
                return result.SetError(compareResult);
            answerCompareResult = compareResult.Data;
            //}
            return result.SetSuccess(answerCompareResult);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="model"></param>
        /// <param name="answerCompareResult"></param>
        /// <returns></returns>
        private static async Task PublishGradeDetailMessage(SubmitAnswerModel model, AnswerCompareResultModel answerCompareResult)
        {
            //var msg = model.MapTo<StudentGradeDetailMessage>();
            //msg.Score = answerCompareResult.Score;
            //msg.AnswerCompareInfo = answerCompareResult.AnswerCompareInfo;
            //msg.AnswerResult = answerCompareResult.AnswerResult;
            //msg.CreateTime = DateTime.Now;

            //var r = await ProducerHepler.PublishAsync(msg);

            var gradeDetai = model.MapTo<StudentGradeDetail>();
            var detail = new List<StudentGradeDetail>();
            detail.Add(gradeDetai);
            await Task.FromResult(detail.Upsert(CommonService.GetEntityDataColumn<StudentGradeDetail>()));
        }

        /// <summary>
        /// 匹配是否有设置多答案的，例如：焦炭厂|焦炭工厂 如果设置了多答案 放弃作答，返回正确答案的时候只返回一个答案即可
        /// </summary>
        /// <param name="questionAnswer"></param>
        /// <returns></returns>
        internal static string QuestionAnswerProcess(string questionAnswer)
        {
            if (questionAnswer == null)
                return null;
            string regex = @"[^""]+?\|[^""]+";//匹配是否有设置多答案的，例如：焦炭厂|焦炭工厂 匹配格式："焦炭厂|焦炭工厂"
            var matchs = Regex.Matches(questionAnswer, regex);
            if (matchs.Count > 0)
            {
                foreach (Match item in matchs)
                {
                    var a = item.Value;
                    var arry = a.Split("|");
                    questionAnswer = questionAnswer.Replace(a, arry[0]);
                }
            }
            return questionAnswer;
        }

        /// <summary>
        /// 是否可以作答校验
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private async Task<ResponseContext<bool>> CheckCanSubmitAnswer(SubmitAnswerModel model)
        {
            var result = new ResponseContext<bool>();
            var exp = StudentGradeDetail._.ProjectId == model.ProjectId
                & StudentGradeDetail._.ConfigId == model.ConfigId
                & StudentGradeDetail._.UserId == model.UserId
                & StudentGradeDetail._.QuestionsId == model.QuestionsId
                ;
            grade = await StudentGradeDetail.FindAsync(exp);//获取作答记录

            //if (grade == null)
            //    return result.SetError("作答主记录不存在。");
            //if (grade.TaskId > 0)
            //{
            //    task = await JxzTask.FindById(grade.TaskId);//校验任务
            //    if (task == null)
            //        return result.SetError("任务不存在。");
            //    errorShowType = task.ErrorShowType;
            //    scoreShowType = task.ScoreShowType;
            //}

            //if (grade.Status == StudentExamStatus.End.GetHashCode())
            //    return result.SetError("已交卷，不能再继续作答。");
            //if (task != null)
            //{
            //    if (task.TaskBeginTime > DateTime.Now)
            //        return result.SetError("任务还没有开始，请等任务开始后再作答。");

            //    if (task.TaskEndTime < DateTime.Now)
            //        return result.SetError("任务已结束，不能继续提交答案。");
            //}

            //var isGiveup = await CheckStudentIsGiveup(model.GradeId, model.QuestionsId);
            //if (isGiveup)
            //    return result.SetError("您已选择放弃答题。");

            return result.SetSuccess(true);
        }
    }
}